/*
 * DataFrame.java
 *
 * Created on den 12 november 2007, 15:44
 */

package grex.Graphics;

import grex.Data.ArffTableModel;
import grex.Options;

import java.awt.FileDialog;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 *
 * @author  RIK
 */
public class DataFrame extends javax.swing.JInternalFrame {
    ArffTableModel model;
    private String TRAIN="TRAIN";
    private String TEST = "TEST";
    private String VAL = "Val";    
    GREXGUI parent;
    /** Creates new form DataFrame */
    public DataFrame(DefaultTableModel model,int nrOfFolds,GREXGUI parent) {
        initComponents();
     //   this.setModal(true);
        this.parent=parent;
        jtxfFold.setText(""+nrOfFolds);
        setClosable(true);
        setModel(model);
    }
    public void setModel(DefaultTableModel model){

        this.model=(ArffTableModel) model;
        this.jfmtNrOfFolds.setValue(this.model.getNrOfFolds());
        jtblData.setModel(model);        
        ArrayList<String> comments = ((ArffTableModel)model).getFileComments();
        for(String str:comments)
            jtxaComments.append(str+"\n");
        jtxaComments.setCaretPosition(0);
        jtblData.validate();
        JTableHeader header = jtblData.getTableHeader();    
        header.addMouseListener(new ColumnHeaderListener());
    }
    public int getNrOfFolds(){
        return (Integer) jfmtNrOfFolds.getValue();
    }

    ArffTableModel getModel() {
        return model;
    }
    
    private void changeMarkerSelection(String value){
        int[] selection = jtblData.getSelectedRows();        
        int markerIndex = model.getColumnCount()-1;
        for (int i = 0; i < selection.length; i++) {
            model.setValueAt(value,selection[i],markerIndex);
        }
    }

    private void addWindowListener(WindowAdapter windowAdapter) {
        //throw new UnsupportedOperationException("Not yet implemented");
    }
    
    public class ColumnHeaderListener extends MouseAdapter {
        public void mouseClicked(MouseEvent evt) {
           if(evt.getClickCount()==2){
            JTable table = ((JTableHeader)evt.getSource()).getTable();
            TableColumnModel colModel = table.getColumnModel();            
            // The index of the column whose header was clicked
            int vColIndex = colModel.getColumnIndexAtX(evt.getX());
            int mColIndex = table.convertColumnIndexToModel(vColIndex);
    
            // Return if not clicked on any column header
            if (vColIndex == -1) {
                return;
            }
    
            // Determine if mouse was clicked between column heads
            Rectangle headerRect = table.getTableHeader().getHeaderRect(vColIndex);
            if (vColIndex == 0) {
                headerRect.width -= 3;    // Hard-coded constant
            } else {
                headerRect.grow(-3, 0);   // Hard-coded constant
            }
            if (!headerRect.contains(evt.getX(), evt.getY())) {
                // Mouse was clicked between column heads
                // vColIndex is the column head closest to the click
    
                // vLeftColIndex is the column head to the left of the click
                int vLeftColIndex = vColIndex;
                if (evt.getX() < headerRect.x) {
                    vLeftColIndex--;
                }
            }
            if(vColIndex<table.getColumnCount()-2&&table.getColumnCount()>3)
                removeColumnAndData(table,vColIndex);             
            table.validate();
        }
        }
        
            public void removeColumnAndData(JTable table, int vColIndex) {       
        ArffTableModel model = (ArffTableModel)table.getModel();        
        
        TableColumn col = table.getColumnModel().getColumn(vColIndex);
        int columnModelIndex = col.getModelIndex();
        Vector data = model.getDataVector();        
        Vector colIds = model.getColumnIdentifiers();
    
        // Remove the column from the table
        table.removeColumn(col);
    
        // Remove the column header from the table model
        colIds.removeElementAt(columnModelIndex);
    
        // Remove the column data
        for (int r=0; r<data.size(); r++) {
            Vector row = (Vector)data.get(r);
            row.removeElementAt(columnModelIndex);
        }
        model.setDataVector(data, colIds);
    
        // Correct the model indices in the TableColumn objects
        // by decrementing those indices that follow the deleted column
        Enumeration enm = table.getColumnModel().getColumns();
        for (; enm.hasMoreElements(); ) {
            TableColumn c = (TableColumn)enm.nextElement();
            if (c.getModelIndex() >= columnModelIndex) {
                c.setModelIndex(c.getModelIndex()-1);
            }
        }
        model.removeColumn(vColIndex);
        model.fireTableStructureChanged();
    }

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        jtblData = new javax.swing.JTable();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        jtxaComments = new javax.swing.JTextArea();
        jpnlCommands = new javax.swing.JPanel();
        jbtnTrain = new javax.swing.JButton();
        jfmtFoldSeed = new javax.swing.JFormattedTextField();
        jfmtNrOfFolds = new javax.swing.JFormattedTextField();
        jbtnTest = new javax.swing.JButton();
        jbtnVal = new javax.swing.JButton();
        jbtnCreateFolds = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jbtnStratify = new javax.swing.JButton();
        jbtnSaveFolds = new javax.swing.JButton();
        jbtnReload = new javax.swing.JButton();
        jbtnTrainTest = new javax.swing.JButton();
        jbtnFuzzyfy = new javax.swing.JButton();
        jftfFuzzySets = new javax.swing.JFormattedTextField();
        jLabel3 = new javax.swing.JLabel();
        jbtnCountSplits = new javax.swing.JButton();
        jlblNrOfSplits = new javax.swing.JLabel();
        jtxfFold = new javax.swing.JTextField();

        setClosable(true);
        setDoubleBuffered(true);
        setPreferredSize(new java.awt.Dimension(116, 200));
        try {
            setSelected(true);
        } catch (java.beans.PropertyVetoException e1) {
            e1.printStackTrace();
        }
        setVisible(true);
        addInternalFrameListener(new javax.swing.event.InternalFrameListener() {
            public void internalFrameActivated(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameClosing(javax.swing.event.InternalFrameEvent evt) {
                formInternalFrameClosing(evt);
            }
            public void internalFrameDeactivated(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameDeiconified(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameIconified(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameOpened(javax.swing.event.InternalFrameEvent evt) {
            }
        });

        jtblData.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jtblData.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
        jScrollPane1.setViewportView(jtblData);

        jTabbedPane1.addTab("Data", jScrollPane1);

        jPanel2.setLayout(new java.awt.BorderLayout());

        jtxaComments.setColumns(20);
        jtxaComments.setEditable(false);
        jtxaComments.setRows(5);
        jScrollPane2.setViewportView(jtxaComments);

        jPanel2.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        jTabbedPane1.addTab("About File", jPanel2);

        getContentPane().add(jTabbedPane1, java.awt.BorderLayout.CENTER);

        jbtnTrain.setText("Set Train"); // NOI18N
        jbtnTrain.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                changeFoldSpecHandler(evt);
            }
        });

        jfmtFoldSeed.setText("1"); // NOI18N
        jfmtFoldSeed.setToolTipText("The seed used to randomize the folds. Set to -1 to use system time."); // NOI18N
        jfmtFoldSeed.setValue(new Integer(1));

        jfmtNrOfFolds.setText("3"); // NOI18N
        jfmtNrOfFolds.setToolTipText("The number of folds that are created when pressing button \"create folds\""); // NOI18N
        jfmtNrOfFolds.setValue(new Integer(4));
        jfmtNrOfFolds.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                jfmtNrOfFoldsFocusLost(evt);
            }
        });

        jbtnTest.setText("Set Test"); // NOI18N
        jbtnTest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                changeFoldSpecHandler(evt);
            }
        });

        jbtnVal.setText("Set Val"); // NOI18N
        jbtnVal.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                changeFoldSpecHandler(evt);
            }
        });

        jbtnCreateFolds.setText("Create folds"); // NOI18N
        jbtnCreateFolds.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnCreateFoldsActionPerformed(evt);
            }
        });

        jLabel1.setText("Nr. of folds"); // NOI18N

        jLabel2.setText("Fold seed"); // NOI18N

        jbtnStratify.setText("Stratify"); // NOI18N
        jbtnStratify.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnStratifyActionPerformed(evt);
            }
        });

        jbtnSaveFolds.setText("Save folds"); // NOI18N
        jbtnSaveFolds.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnSaveFoldsActionPerformed(evt);
            }
        });

        jbtnReload.setText("Reload"); // NOI18N
        jbtnReload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnReloadActionPerformed(evt);
            }
        });

        jbtnTrainTest.setText("Train/Test");
        jbtnTrainTest.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnTrainTestActionPerformed(evt);
            }
        });

        jbtnFuzzyfy.setText("Fuzzyfy");
        jbtnFuzzyfy.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnFuzzyfyActionPerformed(evt);
            }
        });

        jftfFuzzySets.setText("3");
        jftfFuzzySets.setValue(new Integer(3));

        jLabel3.setText("Nr. of sets"); // NOI18N

        jbtnCountSplits.setText("Count Splits");
        jbtnCountSplits.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnCountSplitsActionPerformed(evt);
            }
        });

        jlblNrOfSplits.setText("0");

        jtxfFold.setText("F1");
        jtxfFold.setToolTipText("The fold to count possible splits for");

        javax.swing.GroupLayout jpnlCommandsLayout = new javax.swing.GroupLayout(jpnlCommands);
        jpnlCommands.setLayout(jpnlCommandsLayout);
        jpnlCommandsLayout.setHorizontalGroup(
            jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnlCommandsLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(jpnlCommandsLayout.createSequentialGroup()
                        .addComponent(jbtnTrain)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnVal)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnTest)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jfmtNrOfFolds, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jLabel2))
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jftfFuzzySets, 0, 126, Short.MAX_VALUE)
                    .addComponent(jfmtFoldSeed, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jpnlCommandsLayout.createSequentialGroup()
                        .addComponent(jbtnFuzzyfy)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnCountSplits)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jtxfFold, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(jlblNrOfSplits, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jpnlCommandsLayout.createSequentialGroup()
                        .addComponent(jbtnStratify)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnCreateFolds)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnTrainTest)
                        .addGap(6, 6, 6)
                        .addComponent(jbtnReload)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jbtnSaveFolds))))
        );
        jpnlCommandsLayout.setVerticalGroup(
            jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jpnlCommandsLayout.createSequentialGroup()
                .addGroup(jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                    .addComponent(jbtnTrain)
                    .addComponent(jbtnVal)
                    .addComponent(jbtnTest)
                    .addComponent(jLabel1)
                    .addComponent(jfmtNrOfFolds, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel2)
                    .addComponent(jfmtFoldSeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jbtnStratify)
                    .addComponent(jbtnCreateFolds)
                    .addComponent(jbtnReload)
                    .addComponent(jbtnSaveFolds)
                    .addComponent(jbtnTrainTest))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(jpnlCommandsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbtnFuzzyfy)
                    .addComponent(jftfFuzzySets, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(jbtnCountSplits)
                    .addComponent(jlblNrOfSplits)
                    .addComponent(jtxfFold, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        getContentPane().add(jpnlCommands, java.awt.BorderLayout.PAGE_START);

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-948)/2, (screenSize.height-543)/2, 948, 543);
    }// </editor-fold>//GEN-END:initComponents

    private void changeFoldSpecHandler(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_changeFoldSpecHandler
        if(evt.getSource()==jbtnTrain)
            changeMarkerSelection(TRAIN);
        else if(evt.getSource()==jbtnVal)
            changeMarkerSelection(VAL);
        else if(evt.getSource()==jbtnTest)
            changeMarkerSelection(TEST);
        model.initFoldColumn();
    }//GEN-LAST:event_changeFoldSpecHandler

    private void jbtnCreateFoldsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnCreateFoldsActionPerformed
        model.initFoldColumn((Integer)jfmtNrOfFolds.getValue());
    }//GEN-LAST:event_jbtnCreateFoldsActionPerformed

    private void jbtnStratifyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnStratifyActionPerformed
        model.stratifyData((Integer)jfmtFoldSeed.getValue());
        jbtnStratify.setEnabled(false);
}//GEN-LAST:event_jbtnStratifyActionPerformed

    private void jbtnSaveFoldsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnSaveFoldsActionPerformed
        FileDialog f = new FileDialog(parent,"Choose directory to save files in.",FileDialog.SAVE);
        f.setVisible(true);
        if(f.getFile()!=null)
            model.saveFolds(f.getDirectory(),f.getFile());
        
}//GEN-LAST:event_jbtnSaveFoldsActionPerformed

    private void jbtnReloadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnReloadActionPerformed
        model=model.getOriginalModel();
        jtblData.setModel(model);
     //   jtblData.s
        jtblData.validate();
        jbtnStratify.setEnabled(true);
    }//GEN-LAST:event_jbtnReloadActionPerformed

    private void jbtnTrainTestActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnTrainTestActionPerformed
            model.initTimeSeriesFoldColumn((Integer)jfmtNrOfFolds.getValue());
            jtblData.validate();
    }//GEN-LAST:event_jbtnTrainTestActionPerformed

    private void jbtnFuzzyfyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnFuzzyfyActionPerformed
            model.fuzzit((Integer)jftfFuzzySets.getValue());
            jtblData.validate();
    }//GEN-LAST:event_jbtnFuzzyfyActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
    //    model.setNrOfFolds((Integer)jfmtNrOfFolds.getValue());
    //    parent.updateGUI();
    }//GEN-LAST:event_formWindowClosing

    private void jbtnCountSplitsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnCountSplitsActionPerformed
        model.initFoldColumn((Integer)jfmtNrOfFolds.getValue());
        
        jlblNrOfSplits.setText(""+model.getNumberOfSplits((Integer)jfmtNrOfFolds.getValue()));
        /*if(((Integer)jfmtNrOfFolds.getValue())!=1)
            jlblNrOfSplits.setText(""+model.getNumberOfSplits(jtxfFold.getText()));
        else
            jlblNrOfSplits.setText(""+model.getNumberOfSplits("All data"));*/

    }//GEN-LAST:event_jbtnCountSplitsActionPerformed

    private void jfmtNrOfFoldsFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jfmtNrOfFoldsFocusLost
        model.setNrOfFolds((Integer)jfmtNrOfFolds.getValue());
    }//GEN-LAST:event_jfmtNrOfFoldsFocusLost

    private void formInternalFrameClosing(javax.swing.event.InternalFrameEvent evt) {//GEN-FIRST:event_formInternalFrameClosing
         model.setNrOfFolds((Integer)jfmtNrOfFolds.getValue());
         parent.updateGUI();
         parent.setEnabled(true);
    }//GEN-LAST:event_formInternalFrameClosing
    
    /**
     * @param args the command line arguments
     */
    
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JButton jbtnCountSplits;
    private javax.swing.JButton jbtnCreateFolds;
    private javax.swing.JButton jbtnFuzzyfy;
    private javax.swing.JButton jbtnReload;
    private javax.swing.JButton jbtnSaveFolds;
    private javax.swing.JButton jbtnStratify;
    private javax.swing.JButton jbtnTest;
    private javax.swing.JButton jbtnTrain;
    private javax.swing.JButton jbtnTrainTest;
    private javax.swing.JButton jbtnVal;
    private javax.swing.JFormattedTextField jfmtFoldSeed;
    private javax.swing.JFormattedTextField jfmtNrOfFolds;
    private javax.swing.JFormattedTextField jftfFuzzySets;
    private javax.swing.JLabel jlblNrOfSplits;
    private javax.swing.JPanel jpnlCommands;
    private javax.swing.JTable jtblData;
    private javax.swing.JTextArea jtxaComments;
    private javax.swing.JTextField jtxfFold;
    // End of variables declaration//GEN-END:variables
    
}
